home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xmbase-grok-1.2 / querywin.c < prev    next >
C/C++ Source or Header  |  1995-06-25  |  17KB  |  584 lines

  1. /*
  2.  * Create and destroy default query menu and all widgets in them. All widgets
  3.  * are labels or pushbuttons; they are faster than text buttons. Whenever
  4.  * the user presses a button with text in it, it is overlaid with a Text
  5.  * button. The query menu is started from the form editor, default queries
  6.  * are expressions attached to a form. They appear in the Query pulldown.
  7.  *
  8.  *    add_dquery(form)        apend a query entry to the form's list
  9.  *    destroy_query_window()        remove query popup
  10.  *    create_query_window()        create query popup
  11.  */
  12.  
  13. #include "config.h"
  14. #include <X11/Xos.h>
  15. #include <stdlib.h>
  16. #include <pwd.h>
  17. #include <Xm/Xm.h>
  18. #include <Xm/Form.h>
  19. #include <Xm/LabelP.h>
  20. #include <Xm/LabelG.h>
  21. #include <Xm/PushBP.h>
  22. #include <Xm/PushBG.h>
  23. #include <Xm/ToggleB.h>
  24. #include <Xm/ScrolledW.h>
  25. #include <Xm/Text.h>
  26. #include <Xm/Protocols.h>
  27. #include "grok.h"
  28. #include "form.h"
  29. #include "proto.h"
  30.  
  31. #define NCOLUMNS    4        /* # of widget columns in query list */
  32.  
  33. static void create_query_rows(void);
  34. static void edit_query_button(BOOL, int, int);
  35. static void got_query_text(int, int, char *);
  36. static void draw_row(int);
  37. static void delete_callback(Widget, int, XmToggleButtonCallbackStruct *);
  38. static void dupl_callback  (Widget, int, XmToggleButtonCallbackStruct *);
  39. static void done_callback  (Widget, int, XmToggleButtonCallbackStruct *);
  40. static void list_callback  (Widget, int, XmToggleButtonCallbackStruct *);
  41. static void got_text       (Widget, int, XmToggleButtonCallbackStruct *);
  42.  
  43. extern Display        *display;    /* everybody uses the same server */
  44. extern GC        gc;        /* everybody uses this context */
  45. extern Pixel        color[NCOLS];    /* colors: COL_* */
  46. extern Pixmap        pixmap[NPICS];    /* common symbols */
  47. extern struct config    config;        /* global configuration data */
  48.  
  49. static FORM        *form;        /* form whose queries are edited */
  50. static BOOL        have_shell;    /* message popup exists if TRUE */
  51. static Widget        shell;        /* popup menu shell */
  52. static Widget        delete, dupl;    /* buttons, for desensitizing */
  53. static Widget        info;        /* info line for error messages */
  54. static Widget        textwidget;    /* if editing, text widget; else 0 */
  55. static int        have_nrows;    /* # of table widget rows allocated */
  56. static int        xedit, yedit;    /* if editing, column/row */
  57. static int        ycurr;        /* current row, 0=none, 1=1st query..*/
  58. static Widget        qlist;        /* query list RowColumn widget */
  59. static Widget    (*qtable)[NCOLUMNS];    /* all widgets in query list table */
  60.                     /* [0][*] is title row */
  61.  
  62.  
  63.  
  64. /*
  65.  * add a query entry. This is used when a new entry is started by pressing on
  66.  * an empty row, or when duplicating an entry, or when a form file is read.
  67.  */
  68.  
  69. DQUERY *add_dquery(
  70.     FORM        *fp)        /* form to add blank entry to */
  71. {
  72.     int n = ++fp->nqueries * sizeof(DQUERY);
  73.     if (!(fp->query = (DQUERY *)(fp->query ? realloc((char *)fp->query, n)
  74.                            : malloc(n))))
  75.         fatal("no memory for query");
  76.     mybzero((void *)&fp->query[fp->nqueries-1], sizeof(DQUERY));
  77.     return(&fp->query[fp->nqueries-1]);
  78. }
  79.  
  80.  
  81. /*
  82.  * destroy the popup. Remove it from the screen, and destroy its widgets.
  83.  */
  84.  
  85. void destroy_query_window(void)
  86. {
  87.     if (have_shell) {
  88.         XtPopdown(shell);
  89.         XtDestroyWidget(shell);
  90.         have_shell = FALSE;
  91.     }
  92. }
  93.  
  94.  
  95. /*
  96.  * create a query popup as a separate application shell.
  97.  */
  98.  
  99. void create_query_window(
  100.     FORM            *newform)    /*form whose queries are chgd*/
  101. {
  102.     Widget            wform, scroll, w;
  103.     Arg            args[15];
  104.     int            n;
  105.     Atom            closewindow;
  106.  
  107.     destroy_query_window();
  108.     if (have_shell)
  109.         return;
  110.     form = newform;
  111.     n = 0;
  112.     XtSetArg(args[n], XmNdeleteResponse,    XmUNMAP);        n++;
  113.     XtSetArg(args[n], XmNiconic,        False);            n++;
  114.     shell = XtAppCreateShell("Default Queries", "Grok",
  115.             applicationShellWidgetClass, display, args, n);
  116.     set_icon(shell, 1);
  117.     wform = XtCreateWidget("queryform", xmFormWidgetClass,
  118.             shell, NULL, 0);
  119.     XtAddCallback(wform, XmNhelpCallback,
  120.             (XtCallbackProc)help_callback, (XtPointer)"queries");
  121.  
  122.                             /*-- buttons --*/
  123.     n = 0;
  124.     XtSetArg(args[n], XmNbottomAttachment,    XmATTACH_FORM);        n++;
  125.     XtSetArg(args[n], XmNbottomOffset,    8);            n++;
  126.     XtSetArg(args[n], XmNleftAttachment,    XmATTACH_FORM);        n++;
  127.     XtSetArg(args[n], XmNleftOffset,    8);            n++;
  128.     XtSetArg(args[n], XmNwidth,        80);            n++;
  129.     XtSetArg(args[n], XmNsensitive,        False);            n++;
  130.     delete = w = XtCreateManagedWidget("Delete", xmPushButtonWidgetClass,
  131.             wform, args, n);
  132.     XtAddCallback(w, XmNactivateCallback,
  133.             (XtCallbackProc)delete_callback, (XtPointer)0);
  134.     XtAddCallback(w, XmNhelpCallback,
  135.             (XtCallbackProc)help_callback, (XtPointer)"dq_delete");
  136.  
  137.     n = 0;
  138.     XtSetArg(args[n], XmNbottomAttachment,    XmATTACH_FORM);        n++;
  139.     XtSetArg(args[n], XmNbottomOffset,    8);            n++;
  140.     XtSetArg(args[n], XmNleftAttachment,    XmATTACH_WIDGET);    n++;
  141.     XtSetArg(args[n], XmNleftWidget,    w);            n++;
  142.     XtSetArg(args[n], XmNleftOffset,    8);            n++;
  143.     XtSetArg(args[n], XmNwidth,        80);            n++;
  144.     XtSetArg(args[n], XmNsensitive,        False);            n++;
  145.     dupl = w = XtCreateManagedWidget("Duplicate", xmPushButtonWidgetClass,
  146.             wform, args, n);
  147.     XtAddCallback(w, XmNactivateCallback,
  148.             (XtCallbackProc)dupl_callback, (XtPointer)0);
  149.     XtAddCallback(w, XmNhelpCallback,
  150.             (XtCallbackProc)help_callback, (XtPointer)"dq_dupl");
  151.  
  152.     n = 0;
  153.     XtSetArg(args[n], XmNbottomAttachment,    XmATTACH_FORM);        n++;
  154.     XtSetArg(args[n], XmNbottomOffset,    8);            n++;
  155.     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_FORM);        n++;
  156.     XtSetArg(args[n], XmNrightOffset,    8);            n++;
  157.     XtSetArg(args[n], XmNwidth,        80);            n++;
  158.     w = XtCreateManagedWidget("Done", xmPushButtonWidgetClass,
  159.             wform, args, n);
  160.     XtAddCallback(w, XmNactivateCallback,
  161.             (XtCallbackProc)done_callback, (XtPointer)0);
  162.     XtAddCallback(w, XmNhelpCallback,
  163.             (XtCallbackProc)help_callback, (XtPointer)"dq_done");
  164.  
  165.     n = 0;
  166.     XtSetArg(args[n], XmNbottomAttachment,    XmATTACH_FORM);        n++;
  167.     XtSetArg(args[n], XmNbottomOffset,    8);            n++;
  168.     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_WIDGET);    n++;
  169.     XtSetArg(args[n], XmNrightWidget,    w);            n++;
  170.     XtSetArg(args[n], XmNrightOffset,    8);            n++;
  171.     XtSetArg(args[n], XmNwidth,        80);            n++;
  172.     w = XtCreateManagedWidget("Help", xmPushButtonWidgetClass,
  173.             wform, args, n);
  174.     XtAddCallback(w, XmNactivateCallback,
  175.             (XtCallbackProc)help_callback, (XtPointer)"queries");
  176.     XtAddCallback(w, XmNhelpCallback,
  177.             (XtCallbackProc)help_callback, (XtPointer)"queries");
  178.  
  179.                             /*-- infotext -- */
  180.     n = 0;
  181.     XtSetArg(args[n], XmNleftAttachment,    XmATTACH_FORM);        n++;
  182.     XtSetArg(args[n], XmNleftOffset,    8);            n++;
  183.     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_FORM);        n++;
  184.     XtSetArg(args[n], XmNrightOffset,    8);            n++;
  185.     XtSetArg(args[n], XmNtopAttachment,    XmATTACH_FORM);        n++;
  186.     XtSetArg(args[n], XmNtopOffset,        8);            n++;
  187.     XtSetArg(args[n], XmNalignment,         XmALIGNMENT_BEGINNING);    n++;
  188.     info = XtCreateManagedWidget(" ", xmLabelGadgetClass,
  189.             wform, args, n);
  190.  
  191.                             /*-- scroll --*/
  192.     n = 0;
  193.     XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET);    n++;
  194.     XtSetArg(args[n], XmNtopWidget,        info);            n++;
  195.     XtSetArg(args[n], XmNtopOffset,        8);            n++;
  196.     XtSetArg(args[n], XmNbottomAttachment,    XmATTACH_WIDGET);    n++;
  197.     XtSetArg(args[n], XmNbottomWidget,    w);            n++;
  198.     XtSetArg(args[n], XmNbottomOffset,    16);            n++;
  199.     XtSetArg(args[n], XmNleftAttachment,    XmATTACH_FORM);        n++;
  200.     XtSetArg(args[n], XmNleftOffset,    8);            n++;
  201.     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_FORM);        n++;
  202.     XtSetArg(args[n], XmNrightOffset,    8);            n++;
  203.     XtSetArg(args[n], XmNwidth,        580);            n++;
  204.     XtSetArg(args[n], XmNheight,        300);            n++;
  205.     XtSetArg(args[n], XmNscrollingPolicy,    XmAUTOMATIC);        n++;
  206.     scroll = XtCreateWidget("qscroll", xmScrolledWindowWidgetClass,
  207.             wform, args, n);
  208.     XtAddCallback(scroll, XmNhelpCallback,
  209.             (XtCallbackProc)help_callback, (XtPointer)"queries");
  210.  
  211.     n = 0;
  212.     qlist = XtCreateManagedWidget("qlist", xmBulletinBoardWidgetClass,
  213.             scroll, args, n);
  214.  
  215.     create_query_rows();    /* have_shell must be FALSE here */
  216.     print_query_info();
  217.  
  218.     XtManageChild(scroll);
  219.     XtManageChild(wform);
  220.     XtPopup(shell, XtGrabNone);
  221.  
  222.     closewindow = XmInternAtom(display, "WM_DELETE_WINDOW", False);
  223.     XmAddWMProtocolCallback(shell, closewindow,
  224.             (XtCallbackProc)done_callback, (XtPointer)shell);
  225.     have_shell = TRUE;
  226. }
  227.  
  228.  
  229. /*
  230.  * makes sure there are enough widget rows for query entries. Also makes
  231.  * sure that there aren't too many, for speed reasons. Allocate one extra
  232.  * widget row for the title at the top. All the text buttons are
  233.  * label widgets. For performance reasons, they are overlaid by a text
  234.  * widget when pressed.
  235.  * No text is printed into the buttons, this is done later by draw_row().
  236.  */
  237.  
  238. static short cell_x    [NCOLUMNS] = {  4, 44,  84,  284 };
  239. static short cell_xs   [NCOLUMNS] = { 30, 30, 200, 1000 };
  240. static char *cell_name [NCOLUMNS] = { "on", "def", "Name", "Query Expression"};
  241.  
  242. static void create_query_rows(void)
  243. {
  244.     int            nrows = form->nqueries+3 - form->nqueries%3;
  245.     int            x, y;
  246.     Arg            args[15];
  247.     int            n;
  248.     char            *name;
  249.     WidgetClass        class;
  250.  
  251.     if (!have_shell)                /* check # of rows: */
  252.         have_nrows = 0;
  253.     if (nrows <= have_nrows)
  254.         return;
  255.  
  256.     n = (nrows+1) * NCOLUMNS * sizeof(Widget *);
  257.     if (qtable && !(qtable = (Widget (*)[])realloc(qtable, n)) ||
  258.        !qtable && !(qtable = (Widget (*)[])malloc(n)))
  259.         fatal("no memory");
  260.  
  261.     for (x=0; x < NCOLUMNS; x++) {
  262.         for (y=have_nrows; y <= nrows; y++) {
  263.         XtUnmanageChild(qlist);
  264.         name  = cell_name[x];
  265.         class = xmPushButtonWidgetClass;
  266.         n = 0;
  267.         if (y) {
  268.             if (x < 2) {
  269.                 class = xmToggleButtonWidgetClass;
  270.                 XtSetArg(args[n], XmNselectColor,
  271.                         color[COL_TOGGLE]);    n++;
  272.             }
  273.             if (x == 1) {
  274.                 XtSetArg(args[n], XmNindicatorType,
  275.                         XmONE_OF_MANY);        n++;
  276.             }
  277.             name  = " ";
  278.         } else
  279.             class = xmLabelWidgetClass;
  280.  
  281.         XtSetArg(args[n], XmNx,            cell_x[x]);    n++;
  282.         XtSetArg(args[n], XmNy,            10 + 30*y);    n++;
  283.         XtSetArg(args[n], XmNwidth,        cell_xs[x]);    n++;
  284.         XtSetArg(args[n], XmNheight,        30);        n++;
  285.         XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING);    n++;
  286.         XtSetArg(args[n], XmNrecomputeSize,    False);        n++;
  287.         XtSetArg(args[n], XmNtraversalOn,    True);        n++;
  288.         XtSetArg(args[n], XmNhighlightThickness,0);        n++;
  289.         XtSetArg(args[n], XmNshadowThickness,    x > 1 && y);    n++;
  290.         qtable[y][x] = XtCreateManagedWidget(name, class,
  291.                 qlist, args, n);
  292.         if (y)
  293.             XtAddCallback(qtable[y][x],
  294.                 x > 1 ? XmNactivateCallback
  295.                       : XmNvalueChangedCallback,
  296.                 (XtCallbackProc)list_callback,
  297.                 (XtPointer)((long)(x + y * NCOLUMNS)));
  298.         XtAddCallback(qtable[y][x], XmNhelpCallback,
  299.                 (XtCallbackProc)help_callback,
  300.                 (XtPointer)"queries");
  301.         }
  302.     }
  303.     for (y=have_nrows; y <= nrows; y++)
  304.         draw_row(y);
  305.     have_nrows = nrows;
  306.  
  307.     XtManageChild(qlist);
  308. }
  309.  
  310.  
  311. /*-------------------------------------------------- editing ----------------*/
  312. /*
  313.  * turn a text label into a Text button, to allow user input. This is done
  314.  * by simply installing a text widget on top of the label widget. The proper
  315.  * query name or expression is put into the text widget. The previously edited
  316.  * button is un-edited.
  317.  */
  318.  
  319. static void edit_query_button(
  320.     BOOL            doedit,        /* TRUE=edit, FALSE=unedit */
  321.     int            x,        /* column, 0..NCOLUMNS-1* */
  322.     int            y)        /* row, y=0: title */
  323. {
  324.     Arg            args[15];
  325.     int            n;
  326.     char            *text;
  327.  
  328.     if (textwidget) {
  329.         char *string = XmTextGetString(textwidget);
  330.         got_query_text(xedit, yedit, string);
  331.         XtFree(string);
  332.         XtDestroyWidget(textwidget);
  333.         draw_row(yedit);
  334.         create_query_rows();
  335.     }
  336.     textwidget = 0;
  337.     if (!doedit)
  338.         return;
  339.  
  340.     if (y > form->nqueries+1)
  341.         y = form->nqueries+1;
  342.     n = 0;
  343.     XtSetArg(args[n], XmNx,            cell_x[x]);        n++;
  344.     XtSetArg(args[n], XmNy,            10 + 30*y);        n++;
  345.     XtSetArg(args[n], XmNwidth,        cell_xs[x]);        n++;
  346.     XtSetArg(args[n], XmNheight,        30);            n++;
  347.     XtSetArg(args[n], XmNrecomputeSize,    False);            n++;
  348.     XtSetArg(args[n], XmNpendingDelete,    True);            n++;
  349.     XtSetArg(args[n], XmNhighlightThickness,0);            n++;
  350.     XtSetArg(args[n], XmNshadowThickness,    1);            n++;
  351.     XtSetArg(args[n], XmNbackground,    color[COL_TEXTBACK]);    n++;
  352.     textwidget = XtCreateManagedWidget("text", xmTextWidgetClass,
  353.             qlist, args, n);
  354.     XtAddCallback(textwidget, XmNactivateCallback,
  355.             (XtCallbackProc)got_text, (XtPointer)0);
  356.     XtAddCallback(textwidget, XmNhelpCallback,
  357.             (XtCallbackProc)help_callback, (XtPointer)"queries");
  358.     XmProcessTraversal(textwidget, XmTRAVERSE_CURRENT);
  359.  
  360.     text = y > form->nqueries ? "" : x == 2 ? form->query[y-1].name
  361.                         : form->query[y-1].query;
  362.     print_text_button_s(textwidget, text);
  363.     xedit = x;
  364.     yedit = y;
  365. }
  366.  
  367. static void got_query_text(
  368.     int        x,        /* column, 0..NCOLUMNS-1* */
  369.     int        y,        /* row, y=0: title */
  370.     char        *string)    /* text entered by user */
  371. {
  372.     register DQUERY    *dq;        /* query entry */
  373.  
  374.     if (!y--)
  375.         return;
  376.     if (y >= form->nqueries) {
  377.         (void)add_dquery(form);
  378.         y = form->nqueries - 1;
  379.     }
  380.     dq = &form->query[y];
  381.     if (x == 2) {                    /* name */
  382.         if (dq->name)
  383.             free(dq->name);
  384.         dq->name = mystrdup(string);
  385.     } else {                    /* query expr */
  386.         if (dq->query)
  387.             free(dq->query);
  388.         dq->query = mystrdup(string);
  389.     }
  390. }
  391.  
  392.  
  393. /*
  394.  * draw all buttons of row y. y must be > 0 because 0 is the title row.
  395.  * If y is > form->nqueries, the row is blanked.
  396.  */
  397.  
  398. static void draw_row(
  399.     int        y)
  400. {
  401.     Arg        arg;
  402.     register DQUERY    *dq = &form->query[y-1];
  403.  
  404.     if (y < 1)
  405.         return;
  406.     if (y <= form->nqueries) {                /* valid row */
  407.         XtSetArg(arg, XmNset, !dq->suspended);
  408.         XtSetValues (qtable[y][0], &arg, 1);
  409.         XtSetArg(arg, XmNset, form->autoquery == y-1);
  410.         XtSetValues (qtable[y][1], &arg, 1);
  411.         print_button(qtable[y][2], dq->name  ? dq->name  : " ");
  412.         print_button(qtable[y][3], dq->query ? dq->query : " ");
  413.     } else {                        /* blank row */
  414.         XtSetArg(arg, XmNset, 0);
  415.         XtSetValues (qtable[y][0], &arg, 1);
  416.         XtSetValues (qtable[y][1], &arg, 1);
  417.         print_button(qtable[y][2], " ");
  418.         print_button(qtable[y][3], " ");
  419.     }
  420. }
  421.  
  422.  
  423. /*
  424.  * print interesting info into the message line. This is done only once, when
  425.  * the menu is created.
  426.  */
  427.  
  428. void print_query_info(void)
  429. {
  430.     char        msg[4096];    /* message buffer */
  431.     int        i;        /* index to next free char in msg */
  432.     char        comma = ' ';    /* delimiter between message items */
  433.     int        item;        /* item (field) counter */
  434.     ITEM        *ip;        /* current item (field) */
  435.  
  436.     strcpy(msg, "Fields:");
  437.     i = strlen(msg);
  438.     for (item=0; item < form->nitems; item++) {
  439.         ip = form->items[item];
  440.         switch(ip->type) {
  441.           case IT_INPUT:
  442.           case IT_TIME:
  443.           case IT_NOTE:
  444.             sprintf(msg+i, "%c %s", comma, ip->name);
  445.             break;
  446.  
  447.           case IT_FLAG:
  448.           case IT_CHOICE:
  449.             sprintf(msg+i, "%c %s=%s", comma, ip->name,
  450.                               ip->flagcode);
  451.             break;
  452.  
  453.           default:
  454.             continue;
  455.         }
  456.         i += strlen(msg+i);
  457.         comma = ',';
  458.         if (i > sizeof(msg)-100)
  459.             break;
  460.     }
  461.     if (comma == ' ')
  462.         strcpy(msg+i, "none");
  463.     print_button(info, msg);
  464. }
  465.  
  466.  
  467.  
  468. /*-------------------------------------------------- callbacks --------------*/
  469. /*
  470.  * Delete, Duplicate, and Done buttons.
  471.  * All of these routines are direct X callbacks.
  472.  */
  473.  
  474. /*ARGSUSED*/
  475. static void delete_callback(
  476.     Widget                widget,
  477.     int                item,
  478.     XmToggleButtonCallbackStruct    *data)
  479. {
  480.     int                n;
  481.     Arg                args;
  482.  
  483.     if (ycurr && ycurr <= form->nqueries) {
  484.         edit_query_button(FALSE, 0, 0);
  485.         for (n=ycurr-1; n < form->nqueries; n++)
  486.             form->query[n] = form->query[n+1];
  487.         form->nqueries--;
  488.         for (n=ycurr; n <= have_nrows; n++)
  489.             draw_row(n);
  490.     }
  491.     if (!ycurr) {
  492.         XtSetArg(args, XmNsensitive, 0);
  493.         XtSetValues(delete, &args, 1);
  494.         XtSetValues(dupl,   &args, 1);
  495.     }
  496. }
  497.  
  498.  
  499. /*ARGSUSED*/
  500. static void dupl_callback(
  501.     Widget                widget,
  502.     int                item,
  503.     XmToggleButtonCallbackStruct    *data)
  504. {
  505.     int                n;
  506.  
  507.     if (form->nqueries) {
  508.         edit_query_button(FALSE, 0, 0);
  509.         (void)add_dquery(form);
  510.         create_query_rows();
  511.         for (n=form->nqueries-1; n > ycurr-1; n--)
  512.             form->query[n] = form->query[n-1];
  513.         form->query[n].name  = mystrdup(form->query[n].name);
  514.         form->query[n].query = mystrdup(form->query[n].query);
  515.         for (n=ycurr; n <= form->nqueries; n++)
  516.             draw_row(n);
  517.     }
  518. }
  519.  
  520. /*ARGSUSED*/
  521. static void done_callback(
  522.     Widget                widget,
  523.     int                item,
  524.     XmToggleButtonCallbackStruct    *data)
  525. {
  526.     edit_query_button(FALSE, 0, 0);
  527.     destroy_query_window();
  528.     remake_query_pulldown();
  529. }
  530.  
  531.  
  532. /*
  533.  * one of the buttons in the list was pressed
  534.  */
  535.  
  536. /*ARGSUSED*/
  537. static void list_callback(
  538.     Widget                widget,
  539.     int                item,
  540.     XmToggleButtonCallbackStruct    *data)
  541. {
  542.     int                x = item % NCOLUMNS;
  543.     int                y = item / NCOLUMNS;
  544.     Arg                arg;
  545.     int                i;
  546.  
  547.     if (y > form->nqueries) {                /* new entry */
  548.         x = 2;
  549.         edit_query_button(TRUE, x, ycurr = form->nqueries+1);
  550.     } else {                        /* old entry */
  551.         ycurr = y;
  552.         switch(x) {
  553.           case 0:
  554.             form->query[y-1].suspended = !data->set;
  555.             break;
  556.           case 1:
  557.             i = form->autoquery;
  558.             form->autoquery = y-1;
  559.             draw_row(i+1);
  560.             draw_row(y);
  561.             break;
  562.           default:
  563.             edit_query_button(TRUE, x, y);
  564.         }
  565.     }
  566.     XtSetArg(arg, XmNsensitive, ycurr > 0);
  567.     XtSetValues(delete, &arg, 1);
  568.     XtSetValues(dupl,   &arg, 1);
  569. }
  570.  
  571.  
  572. /*
  573.  * the user pressed Return in a text entry button
  574.  */
  575.  
  576. /*ARGSUSED*/
  577. static void got_text(
  578.     Widget                widget,
  579.     int                item,
  580.     XmToggleButtonCallbackStruct    *data)
  581. {
  582.     edit_query_button(FALSE, 0, 0);
  583. }
  584.